﻿
Imports System.Text
Imports iConverter.Contracts
Imports System.IO
Imports iConverter.Core
Imports System.ComponentModel


Namespace Models




    ''' <summary>
    ''' 转换文档
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ConvertDocument
        Implements IConvertDocument, IDisposable, INotifyPropertyChanged

#Region "INotifyPropertyChanged 的实现 "

        ''' <summary>
        ''' 用来引发 PropertyChanged 事件，当属性被更改之后
        ''' </summary>
        ''' <param name="propName">属性名字</param>
        Private Sub Notify(ByVal propName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
        End Sub

        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

#End Region

        ''' <summary>
        ''' 文件名
        ''' </summary>
        ''' <remarks></remarks>
        Dim _filename As String
        ''' <summary>
        ''' 文档是否已经转换
        ''' </summary>
        ''' <remarks></remarks>
        Dim _IsConverted As Boolean
        ''' <summary>
        ''' 从上次保存文档后是否修改过
        ''' </summary>
        ''' <remarks></remarks>
        Dim _IsChanged As Boolean


        ''' <summary>
        ''' 创建新的实例
        ''' </summary>
        ''' <remarks>
        ''' 用来限制在其他位置构造文档
        ''' </remarks>
        Friend Sub New()
            MyClass.New(String.Empty, String.Empty)
        End Sub





        ''' <summary>
        ''' 创建新的实例
        ''' </summary>
        ''' <param name="filename">文件名</param>
        ''' <param name="content">文档内容</param>
        ''' <remarks>
        ''' 用来限制在其他位置构造文档
        ''' </remarks>
        Friend Sub New(ByVal filename As String, ByVal content As String)
            Me._filename = filename
            Me._content = content
        End Sub


        Private _name As String
        ''' <summary>
        ''' 获取或设置文档名称
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
                Me.Notify("Name")
            End Set
        End Property

        ''' <summary>
        ''' 获取文件名
        ''' </summary>
        ''' <value>包含文件名的完整字符串</value>
        ''' <returns>返回包含完整路径的文件名。如果文档内容不是来至文件，则返回空串“”。</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FileName As String Implements IConvertDocument.FileName
            Get
                Return _filename
            End Get
        End Property

        ''' <summary>
        ''' 获取文档是否已经转换
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property IsConverted As Boolean
            Get
                Return _IsConverted
            End Get
        End Property

        ''' <summary>
        ''' 获取文档从上次保存文档后是否修改过
        ''' </summary>
        ''' <value></value>
        ''' <returns>如果修改过着返回True，否则返回False</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property IsChanged As Boolean Implements IConvertDocument.IsChanged
            Get
                Return _IsChanged
            End Get
        End Property


        ''' <summary>
        ''' 文档内容
        ''' </summary>
        Private _content As String
        ''' <summary>
        ''' 获取或设置文档内容
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Content() As String Implements IConvertDocument.Content
            Get
                Return _content
            End Get
            Set(ByVal value As String)
                _content = value
                Me._IsChanged = True

                Me.Notify("Content")
                Me.Notify("IsChanged")
            End Set
        End Property



        Private _contentEncoding As Encoding
        ''' <summary>
        ''' 获取或设置文档内容编码
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>
        ''' 用来表示文档内容的编码，对于手工输入的内容，系统编码的可能性较高
        ''' </remarks>
        Public Property ContentEncoding() As Encoding
            Get
                Return _contentEncoding
            End Get
            Set(ByVal value As Encoding)
                _contentEncoding = value
                Me.Notify("ContentEncoding")
            End Set
        End Property


        Private _sourceEncoding As Encoding
        ''' <summary>
        ''' 获取或设置源字符编码
        ''' </summary>
        Public Property SourceEncoding() As Encoding
            Get
                Return _sourceEncoding
            End Get
            Set(ByVal value As Encoding)
                _sourceEncoding = value
                Me.Notify("SourceEncoding")
            End Set
        End Property

        Private _destinationEncoding As Encoding
        ''' <summary>
        ''' 获取或设置目标字符编码
        ''' </summary>
        Public Property DestinationEncoding() As Encoding
            Get
                Return _destinationEncoding
            End Get
            Set(ByVal value As Encoding)
                _destinationEncoding = value

                Me.Notify("DestinationEncoding")
            End Set
        End Property







#Region "保存"



        ''' <summary>
        ''' 保存文件
        ''' </summary>
        ''' <param name="isBackup">是否备份</param>
        ''' <remarks></remarks>
        Public Sub Save(ByVal isBackup As Boolean)
            If Me.IsFromFile Then
                SaveToFile(isBackup, Me.FileName)
            Else
                SaveToTempFile()
            End If
        End Sub

        ''' <summary>
        ''' 保存文件
        ''' </summary>
        ''' <param name="isBackup">是否备份</param>
        ''' <param name="filename">要保存的文件名</param>
        ''' <remarks></remarks>
        Public Sub SaveToFile(ByVal isBackup As Boolean, ByVal filename As String)
            SaveToFileWithEncoding(isBackup, filename, Me.DestinationEncoding)
        End Sub

        ''' <summary>
        ''' 保存到文件并使用指定的编码
        ''' </summary>
        ''' <param name="isBackup">是否备份</param>
        ''' <param name="filename">要保存的文件名</param>
        ''' <param name="encoding">编码</param>
        ''' <remarks></remarks>
        Public Sub SaveToFileWithEncoding(ByVal isBackup As Boolean, ByVal filename As String, ByVal encoding As Encoding)
            'If Not File.Exists(filename) Then
            '    Throw New InvalidOperationException()
            'End If

            Dim fi As New FileInfo(filename)

            If fi.Exists AndAlso isBackup Then
                Dim backupFilename = If(isBackup, IO.Path.ChangeExtension(fi.Name, fi.Extension & ".bak"), String.Empty)
                If My.Computer.FileSystem.FileExists(backupFilename) Then My.Computer.FileSystem.DeleteFile(backupFilename, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
                My.Computer.FileSystem.RenameFile(fi.FullName, backupFilename)
            End If


            My.Computer.FileSystem.WriteAllText(fi.FullName, Me.Content, False, encoding)


            Me._IsChanged = False
            Me._filename = fi.FullName

            Me.Notify("IsChanged")
            Me.Notify("FileName")
        End Sub
        ''' <summary>
        ''' 保存到临时文件
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub SaveToTempFile()
            Dim filename = Path.GetTempFileName

            Me.SaveToFile(False, filename)
        End Sub

#End Region




        ''' <summary>
        ''' 关闭文档
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Close()
            Me.Dispose()
        End Sub


        ''' <summary>
        ''' 设置转换完成标记
        ''' </summary>
        ''' <remarks>此方法仅限内部调用</remarks>
        Friend Sub SetIsConverteDone()
            Me._IsConverted = True
            Me.Notify("IsConverted")
        End Sub


#Region "IConvertDocument 支持"

        ''' <summary>
        ''' 获取源字符编码
        ''' </summary>
        Public Function GetDestinationEncoding() As System.Text.Encoding Implements Contracts.IConvertDocument.GetDestinationEncoding
            Return DestinationEncoding
        End Function

        ''' <summary>
        ''' 获取目标字符编码
        ''' </summary>
        Public Function GetSourceEncoding() As System.Text.Encoding Implements Contracts.IConvertDocument.GetSourceEncoding
            Return SourceEncoding
        End Function
#End Region





#Region "IDisposable Support"
        Private disposedValue As Boolean ' 检测冗余的调用

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    '  释放托管状态(托管对象)。

                    Me._content = Nothing
                    Me._filename = Nothing


                End If

                '  释放非托管资源(非托管对象)并重写下面的 Finalize()。
                '  将大型字段设置为 null。
            End If
            Me.disposedValue = True
        End Sub

        ' 仅当上面的 Dispose(ByVal disposing As Boolean)具有释放非托管资源的代码时重写 Finalize()。
        'Protected Overrides Sub Finalize()
        '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' Visual Basic 添加此代码是为了正确实现可处置模式。
        Public Sub Dispose() Implements IDisposable.Dispose
            ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region




    End Class


End Namespace
